;;====================================================================
;;
;; .emacs
;;
;;     1. custom-set-variables
;;     2. custom-set-faces
;;     3. other variables
;;     4. functions
;;     5. packages
;;     6. keybindings
;;     7. hooks, auto-mode
;;
;;====================================================================


;;========= custom-set-variables =====================================
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(column-number-mode t)
 '(global-linum-mode t)
 '(initial-scratch-message
   ";; Hver maður er borinn frjáls og jafn öðrum að virðingu og réttindum.
;; Menn eru gæddir vitsmunum og samvisku, og ber þeim að breyta bróðurlega
;; hverjum við annan.")
 '(package-selected-packages
   (quote
    (auto-complete
     ac-c-headers
     csharp-mode
     cyberpunk-2019-theme
     elm-mode
     groovy-mode
     haskell-mode
     helm
     helm-projectile
     iedit
     lua-mode
     markdown-mode
     minimap
     mutt-mode
     projectile
     web-mode
     yaml-mode
     zenburn-theme)))
 '(scroll-bar-mode nil)
 '(show-paren-mode t)
 '(tool-bar-mode nil))


;;========= custom-set-faces =========================================
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )


;;========= other variables ==========================================
(set-face-attribute 'default nil :height 80)

(setq
 backup-directory-alist '(("." . "~/.emacs.d/backup"))
 backup-by-copying      t ; Don't delink hardlinks
 version-control        t ; Use version numbers on backups
 delete-old-versions    t ; Automatically delete excess backups
 kept-new-versions     20 ; how many of the newest versions to keep
 kept-old-versions      5 ; and how many of the old
 )

(setq
 helm-split-window-in-side-p            t ; open helm buffer inside current window, not occupy whole other window
 helm-move-to-line-cycle-in-source      t ; move to end or beginning of source when reaching top/bottom of source.
 helm-ff-search-library-in-sexp         t ; search for library in `require' and `declare-function' sexp.
 helm-scroll-amount                     8 ; scroll 8 lines other window using M-<next>/M-<prior>
 helm-ff-file-name-history-use-recentf  t ;
 helm-echo-input-in-header-line         t ;
 helm-left-margin-width                 4 ;
 helm-autoresize-max-height             0 ;
 helm-autoresize-min-height            40 ;
 )

(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
(setq indent-according-to-mode t)


;;========= functions ================================================
(defun my:delete-trailing-whitespace-entire-buffer ()
  "Remove all trailing whitespace for the current buffer."
  (interactive)
  (delete-trailing-whitespace (point-min) (point-max)))

(defun my:find-file-config ()
  "Open the emacs dotfile."
  (interactive)
  (let ((my-dotfile "~/.emacs"))
    (if (file-exists-p my-dotfile)
        (find-file my-dotfile)
      (message "WARNING: missing %s" my-dotfile))))

(defun my:init-ac-c-header ()
  "Initialize auto-complete-c-headers for c/c++ hooks"
  (add-to-list 'ac-sources 'ac-source-c-headers)
  (add-to-list 'ac-sources 'ac-source-c-header-symbols t))

(defun my:load-theme ()
  "Load the theme file from the optional script if it exists."
  (let ((my-file "~/.emacs.d/opt/my-theme-file.el"))
    (if (file-exists-p my-file)
        (progn
          (message (concat "Loading " (expand-file-name my-file)))
          (add-to-list 'load-path (expand-file-name (file-name-directory my-file)))
          (require 'my-theme-file))
      (message "WARNING: missing %s" my-file))))

(defun my:package-install-missing-packages ()
  "Automatically install missing packages. Only touch the network if necessary."
  (dolist (element package-selected-packages)
    (unless (package-installed-p element)
      (progn
        (message "WARNING: missing package %s" element)
        (unless package-archive-contents
          (package-refresh-contents))
        (package-install element)))))

(defun my:set-frame-parameter-transparency (value)
  "Set the alpha/opacity/transparency of the frame window.
Where alpha value 0 is transparent and 100 is opaque."
  (interactive "nOpacity Value <0..100>:")
  (set-frame-parameter (selected-frame) 'alpha value))

(defun my:toggle-comment-region-or-line ()
  "Comment or uncomment a region or the current line."
  (interactive)
  (let (beg end)
    (if (region-active-p)
        (setq beg (region-beginning) end (region-end))
      (setq beg (line-beginning-position) end (line-end-position)))
    (comment-or-uncomment-region beg end)
    (next-line)))

(defun my:untabify-entire-buffer ()
  "Convert all tabs to spaces for the current buffer."
  (interactive)
  (untabify (point-min) (point-max)))

(defun my:web-mode-hook ()
  "Hooks for Web mode."
  (setq
   web-mode-markup-indent-offset 2
   web-mode-css-indent-offset    2
   web-mode-code-indent-offset   2
   web-mode-attr-indent-offset   2
   web-mode-style-padding        0
   web-mode-script-padding       0
   web-mode-block-padding        0
   )
  (add-to-list 'web-mode-indentation-params '("lineup-args" . nil))
  (add-to-list 'web-mode-indentation-params '("lineup-calls" . nil))
  (add-to-list 'web-mode-indentation-params '("lineup-concats" . nil))
  (add-to-list 'web-mode-indentation-params '("lineup-ternary" . nil)))


;;========= packages =================================================
(require 'package)
(add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/"))
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(when (< emacs-major-version 27)
  (package-initialize))
(my:package-install-missing-packages)

(require 'auto-complete)
(require 'auto-complete-config)
(ac-config-default)
(require 'ac-c-headers)

(require 'helm)
(require 'helm-config)
(helm-autoresize-mode 1)
(helm-mode 1)

(require 'helm-projectile)
(helm-projectile-on)

(require 'iedit)
(require 'org-id)

(my:load-theme)


;;========= keybindings ==============================================
(global-set-key (kbd "<f12>") 'my:find-file-config)
(global-set-key (kbd "<f5>") 'revert-buffer)
(global-set-key (kbd "<f6>") 'highlight-regexp)
(global-set-key (kbd "<f7>") 'cua-rectangle-mark-mode)
(global-set-key (kbd "<f9>") 'eval-buffer)
(global-set-key (kbd "C-c <f2>") 'iedit-mode)
(global-set-key (kbd "C-c <f3>") 'my:untabify-entire-buffer)
(global-set-key (kbd "C-c <f4>") 'my:delete-trailing-whitespace-entire-buffer)
(global-set-key (kbd "C-x C-;") 'my:toggle-comment-region-or-line)
(global-set-key (kbd "C-x RET DEL") 'projectile-kill-buffers)
(global-set-key (kbd "C-x RET a") 'helm-projectile-find-file)
(global-set-key (kbd "C-x RET j") 'projectile-mode)
(global-set-key (kbd "C-x RET s") 'sort-lines)


;;========= hooks ====================================================
(add-hook 'c++-mode-hook 'my:init-ac-c-header)
(add-hook 'c-mode-hook 'my:init-ac-c-header)
(add-hook 'dired-mode-hook 'dired-hide-details-mode)
(add-hook 'web-mode-hook 'my:web-mode-hook)

(add-to-list 'auto-mode-alist '("\\.css\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.jinja2\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.js\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.vue\\'" . web-mode))
